package cn.iocoder.yudao.module.design.service.problem;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.design.asyncworker.flowTask.ProblemRelEndTaskNotifyWorker;
import cn.iocoder.yudao.module.design.asyncworker.flowTask.ProblemRelUnTaskNotifyWorker;
import cn.iocoder.yudao.module.design.controller.admin.problem.vo.*;
import cn.iocoder.yudao.module.design.convert.problem.ProblemConvert;
import cn.iocoder.yudao.module.design.dal.dataobject.problem.ProblemCountDO;
import cn.iocoder.yudao.module.design.dal.dataobject.problem.ProblemDO;
import cn.iocoder.yudao.module.design.dal.mysql.problem.ProblemMapper;
import cn.iocoder.yudao.module.design.service.houseUserRel.HouseUserRelService;
import com.tlcsdm.async.executor.Async;
import com.tlcsdm.async.executor.timer.SystemClock;
import com.tlcsdm.async.wrapper.WorkerWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.design.enums.ErrorCodeConstants.PROBLEM_NOT_EXISTS;

/**
 * 项目问题 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class ProblemServiceImpl implements ProblemService {


    @Resource
    private ProblemMapper problemMapper;

    @Resource
    private HouseUserRelService houseUserRelService;


    @Override
    public Long createProblem(ProblemCreateReqVO createReqVO) {
        // 插入
        ProblemDO problem = ProblemConvert.INSTANCE.convert(createReqVO);
        problem.setUserId(SecurityFrameworkUtils.getLoginUserId());
        problem.setDeleted(false);
        problem.setStatus("1"); // 1待解决 0已解决 2 关闭
        problemMapper.insert(problem);



        // 返回
        return problem.getId();
    }

    @Override
    public void updateProblem(ProblemUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateProblemExists(updateReqVO.getId());
        // 更新
        ProblemDO updateObj = ProblemConvert.INSTANCE.convert(updateReqVO);
        if("0".equals(updateObj.getStatus())){
            updateObj.setFinishTime(new Date());
        }
        problemMapper.updateById(updateObj);

    }

    @Override
    public void updateProblemStatus(ProblemUpdateReqVO updateReqVO) {

        // 校验存在
        this.validateProblemExists(updateReqVO.getId());
        // 更新
        ProblemDO updateObj = problemMapper.selectById(updateReqVO.getId());
        // 0 已解决 1 进行中 2 关闭 3挂起  4 中止
        if("0".equals(updateObj.getStatus())){
            updateObj.setFinishTime(new Date());
        }
        if(ObjectUtil.isNotNull(updateReqVO.getSolution())){
            updateObj.setSolution(updateReqVO.getSolution());
        }else{
            updateObj.setSolution("");
        }

        updateObj.setStatus(updateReqVO.getStatus());
        problemMapper.updateById(updateObj);

    }

    /**
     * @param id
     * @param statusCd
     */
    @Override
    public void updateProblemStatus(Long id, String statusCd) {
        // 校验存在
        this.validateProblemExists(id);
        // 更新
        ProblemDO updateObj = problemMapper.selectById(id);
        // 0 已解决 1 进行中 2 关闭 3挂起  4 中止
        if("0".equals(updateObj.getStatus())){
            updateObj.setFinishTime(new Date());
        }
        updateObj.setStatus(statusCd);
        problemMapper.updateById(updateObj);
    }

    /**
     * 修改问题状态
     *
     * @param id
     * @param statusCd
     * @throws
     * @author Annie
     * @time 2023/7/28 15:15
     * @param[1] id 问题id
     * @param[2] statusCd  状态
     */
    @Override
    public void updateRelHandUpStatus(Long id, String statusCd) {
        problemMapper.updateRelHandUpStatus(id,statusCd);
    }

    @Override
    public void deleteProblem(Long id) {
        // 校验存在
        this.validateProblemExists(id);
        // 删除
        problemMapper.deleteById(id);
    }

    private void validateProblemExists(Long id) {
        if (problemMapper.selectById(id) == null) {
            throw exception(PROBLEM_NOT_EXISTS);
        }
    }

    @Override
    public ProblemDO getProblem(Long id) {
        return problemMapper.selectById(id);
    }
   /*
    * 根据问题Id 查询问题详情
    * @author Annie
    * @time 2023/7/27 17:01
    * @param[1] id
    * @return ProblemRespDetailVO
    * @throws
    */
    @Override
    public ProblemRespDetailVO getProblemData(Long id) {
        ProblemDO problem = problemMapper.selectById(id);
        ProblemRespDetailVO convert = ProblemConvert.INSTANCE.convertDetail(problem);


        return convert;
    }

    @Override
    public List<ProblemDO> getProblemList(Collection<Long> ids) {
        return problemMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ProblemDO> getProblemPage(ProblemPageReqVO pageReqVO) {

        return problemMapper.selectPageInIds(pageReqVO);
    }

   

    @Override
    public List<ProblemDO> getProblemList(ProblemExportReqVO exportReqVO) {
        return problemMapper.selectList(exportReqVO);
    }

    /**
     * 查询个人需要处理的每个项目问题
     *
     * @param houseIds
     * @return
     */
    @Override
    public List<ProblemCountDO> getProblemCount(Collection<Long> houseIds) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        List<ProblemCountDO> problemCountDOS = problemMapper.selectProblemCountList(houseIds, userId);
        return problemCountDOS;
    }

    /**
   *  查询个人需要处理的项目问题数量(待解决 和 已解决待处理的)
   *
   * @author Annie
   * @time 2023/7/27 17:22
   * @param[1] houseId
   * @return int
   * @throws
   */
    @Override
    public int getProblemCount(Long houseId) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        return problemMapper.selectHouseUserProblemCount( houseId,userId);

    }

    /**
     *  查询指定状态关联问题列表
     * @param problemId
     * @param statusCd
     * @return
     */
    @Override
    public List<ProblemDO> getRelProblemList(Long problemId, String statusCd) {

        return problemMapper.getRelProblemList(problemId,statusCd);
    }

    /**
     *
     * 查询关联问题 未完成的问题列表
     * @author czw
     * @time 2023/7/30 14:07
     * @param[1] problemId
     * @param[2] statusCd
     */
    @Override
    public List<ProblemDO> getRelUnProblemList(Long problemId) {
        return problemMapper.getRelUnProblemList(problemId);
    }

    /**
     * 异步编排问题处理结果通知
     *
     * @param problemId
     * @throws
     * @author Administrator
     * @time 2023/7/30 14:48
     * @param[1] problemId
     */
    @Override
    public void dealProblemNotifyWorker(Long problemId) {
        ProblemRelEndTaskNotifyWorker w = new ProblemRelEndTaskNotifyWorker();
        ProblemRelUnTaskNotifyWorker w1 = new ProblemRelUnTaskNotifyWorker();

        WorkerWrapper<String, String> workerWrapper1 =  new WorkerWrapper.Builder<String, String>()
                .worker(w1)
                .callback(w1)
                .param(String.valueOf(problemId))
                .build();

        WorkerWrapper<String, String> workerWrapper =  new WorkerWrapper.Builder<String, String>()
                .worker(w)
                .callback(w)
                .param(String.valueOf(problemId))
                .build();
        long now = SystemClock.now();
        log.debug("begin-" + now);

        try {
            Async.beginWork(100, workerWrapper, workerWrapper1);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("异步编排问题处理结果通知 异常"+e.getMessage());
        }
        log.debug("end-" + SystemClock.now());
        log.debug("cost-" + (SystemClock.now() - now));
    }


    @Override
    public List<ProblemDO> getProblemSimInfo(ProblemSimReqVO context) {


        return    problemMapper.getUnRelProblemList(context.getProblemId(),context.getHouseId(),SecurityFrameworkUtils.getLoginUserId());
    }

    /**
     * @param context
     */
    @Override
    public void addRelProblem(ProblemRelReqVO context) {

    }

    /**
     * @param context
     * @return
     */
    @Override
    public List<ProblemDO> getPreProblemSimList(ProblemSimReqVO context) {

        return problemMapper.getPreRelProblemList(context.getProblemId(),context.getTitle() );
    }

    @Override
    public void createProblemDealerIds(List<Long> dealerIds, Long problemId) {

    }


}
